package io.kiki.stack.http.feign;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Collection;

/**
 * An implementation of {@link ResponseInterceptor} the returns the value of the location header
 * when appropriate.
 */
public class RedirectionInterceptor implements ResponseInterceptor {
    @Override
    public Object intercept(InvocationContext invocationContext, ResponseInterceptorChain responseInterceptorChain) throws Exception {
        Response response = invocationContext.response();
        int status = response.status();
        Object returnValue = null;
        if (300 <= status && status < 400 && response.headers().containsKey("Location")) {
            Type returnType = rawType(invocationContext.returnType());
            Collection<String> locations = response.headers().get("Location");
            if (Collection.class.equals(returnType)) {
                returnValue = locations;
            } else
                if (String.class.equals(returnType)) {
                    if (locations.isEmpty()) {
                        returnValue = "";
                    } else {
                        returnValue = locations.stream().findFirst().orElse("");
                    }
                }
        }
        if (returnValue == null) {
            return responseInterceptorChain.next(invocationContext);
        } else {
            response.close();
            return returnValue;
        }
    }

    private Type rawType(Type type) {
        return type instanceof ParameterizedType ? ((ParameterizedType) type).getRawType() : type;
    }
}
